import 'dart:io';
import 'dart:ui' as ui;
import "package:ct_pa_majordomo/config/theme_vars.dart";
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import "package:flutter_easyloading/flutter_easyloading.dart";
import 'dart:math' as math;
import 'dart:async';

import "package:flutter_image_compress/flutter_image_compress.dart";
import "package:qr_flutter/qr_flutter.dart";
import 'package:share_plus/share_plus.dart';

abstract final class Utils {
  static bool isEmpty(data) => data == null || data.isEmpty;

  static bool isNotEmpty(data) => data != null && data.isNotEmpty;

  /// 节流函数
  /// [callback] 需要执行的函数
  /// [milliseconds] 节流时间（毫秒）
  /// 返回一个新的函数，在指定时间内只会执行一次
  static Function throttle(Function callback, int milliseconds) {
    DateTime? lastTime;
    Timer? timer;
    
    return () {
      final now = DateTime.now();
      
      // 如果是第一次调用或者已经超过节流时间
      if (lastTime == null || now.difference(lastTime!).inMilliseconds > milliseconds) {
        lastTime = now;
        return callback();
      }
      
      // 如果在节流时间内，取消之前的定时器并设置新的定时器
      if (timer != null) {
        timer!.cancel();
      }
      
      // 计算剩余时间
      final remaining = milliseconds - now.difference(lastTime!).inMilliseconds;
      
      // 设置定时器，在剩余时间后执行
      timer = Timer(Duration(milliseconds: remaining), () {
        lastTime = DateTime.now();
        callback();
      });
    };
  }


  /// 防抖函数
  /// [callback] 需要执行的函数
  /// [milliseconds] 防抖时间（毫秒）
  /// 返回一个新的函数，在指定时间内只会执行一次
  static Function debounce(Function callback, int milliseconds) {
    Timer? timer;
    return () {
      if (timer != null) {
        timer!.cancel();
      }
      timer = Timer(Duration(milliseconds: milliseconds), () {
        callback();
      });
    };
  }

  ///千分位转换
  static String formatCurrency(double amount) {
    // 首先，使用toStringAsFixed将double转换为字符串，并保留两位小数
    String numberStr = amount.toStringAsFixed(2);

    // 分割整数部分和小数部分
    List<String> parts = numberStr.split(".");
    String integerPart = parts[0];
    String decimalPart = parts.length > 1 ? ".${parts[1]}" : "";

    // 使用正则表达式和replaceAllMapped在整数部分插入千分位分隔符
    String formattedIntegerPart = integerPart.replaceAllMapped(
      RegExp(r"(?<=\d)(?=(\d{3})+(?!\d))"),
      (match) => ",",
    );

    // 拼接整数部分和小数部分
    return formattedIntegerPart + decimalPart;
  }

  ///转换成double
  static double toDouble(dynamic data) {
    try {
      if (data is int || data is num) {
        return data.toDouble();
      } else if (data is String) {
        return double.parse(data);
      } else if (data is double) {
        return data;
      }
    } catch (error) {
      print("toDouble error:>>>>> $error");
    }
    return 0;
  }

  /// 获取文件大小（MB）
  static double getFileSizeInMB(File file) {
    return file.lengthSync() / (1024 * 1024);
  }

  /// 压缩图片
  /// [file] 要压缩的图片文件
  /// [maxWidth] 最大宽度
  /// [maxHeight] 最大高度
  /// [quality] 压缩质量 0-100
  /// [targetSizeInMB] 目标大小（MB）
  /// [currentAttempt] 当前尝试次数
  static Future<File> compressImage(
    File file, {
    int maxWidth = 1024,
    int maxHeight = 1024,
    int quality = 85,
    double targetSizeInMB = 1.0,
    int currentAttempt = 1,
  }) async {
    try {
      if (!file.existsSync()) {
        throw Exception('File does not exist: ${file.path}');
      }

      // 检查当前文件大小
      final currentSizeInMB = getFileSizeInMB(file);
      print('Current file size: ${currentSizeInMB.toStringAsFixed(2)}MB, attempt: $currentAttempt, quality: $quality');

      // 如果已经小于目标大小，直接返回
      if (currentSizeInMB <= targetSizeInMB) {
        return file;
      }

      // 如果尝试次数过多，说明无法达到目标大小
      if (currentAttempt > 3) {
        throw Exception('Unable to compress image to target size after multiple attempts');
      }

      // 根据文件大小设置初始压缩质量
      if (currentAttempt == 1) {
        quality = currentSizeInMB >= 2 ? 80 : 50; // >=2M压缩20%，<2M压缩50%
      }

      // 读取图片文件
      final bytes = await file.readAsBytes();
      final codec = await ui.instantiateImageCodec(bytes);
      final frame = await codec.getNextFrame();
      final image = frame.image;

      // 计算压缩后的尺寸
      double ratio = 1.0;
      if (image.width > maxWidth || image.height > maxHeight) {
        ratio = math.min(
          maxWidth / image.width,
          maxHeight / image.height,
        );
      }

      final targetWidth = (image.width * ratio).round();
      final targetHeight = (image.height * ratio).round();

      // 创建临时文件路径
      final dir = Directory.systemTemp;
      final targetPath = '${dir.path}/compressed_${DateTime.now().millisecondsSinceEpoch}.jpg';
      
      // 确保目标目录存在
      if (!dir.existsSync()) {
        dir.createSync(recursive: true);
      }

      // 创建画布并绘制图片
      final pictureRecorder = ui.PictureRecorder();
      final canvas = Canvas(pictureRecorder);
      
      canvas.drawImageRect(
        image,
        Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()),
        Rect.fromLTWH(0, 0, targetWidth.toDouble(), targetHeight.toDouble()),
        Paint()..filterQuality = FilterQuality.high,
      );

      final picture = pictureRecorder.endRecording();
      final ui.Image resizedImage = await picture.toImage(targetWidth, targetHeight);
      
      // 将图片编码为字节数据
      final byteData = await resizedImage.toByteData(format: ui.ImageByteFormat.png);
      final buffer = byteData!.buffer.asUint8List();

      // 保存压缩后的图片
      final compressedFile = File(targetPath);
      await compressedFile.writeAsBytes(buffer);

      // 检查压缩后的大小，如果仍然太大，递归压缩
      final compressedSizeInMB = getFileSizeInMB(compressedFile);
      print('Compressed size: ${compressedSizeInMB.toStringAsFixed(2)}MB with quality: $quality');

      if (compressedSizeInMB > targetSizeInMB) {
        // 降低质量继续压缩
        final newQuality = (quality * 0.7).round(); // 每次再压缩30%
        return compressImage(
          compressedFile,
          maxWidth: (targetWidth * 0.9).round(),
          maxHeight: (targetHeight * 0.9).round(),
          quality: newQuality,
          targetSizeInMB: targetSizeInMB,
          currentAttempt: currentAttempt + 1,
        );
      }

      return compressedFile;
    } catch (e, stackTrace) {
      print('Image compression error: $e');
      print('Stack trace: $stackTrace');
      throw Exception('Image compression failed: ${e.toString()}');
    }
  }

  /// 生成二维码弹窗
  static void showQRCode(BuildContext context, {required String url, String? title, String? tip}) {
    
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: title != null ? Text(title) : null,
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              GestureDetector(
                onLongPress: () => _saveQRCode(context, url),
                child: Container(
                  width: 200,
                  height: 200,
                  child: QrImageView(
                    data: url,
                    size: 200.0,
                  ),
                ),
              ),
              const SizedBox(height: 16),
              if (tip != null) Text(tip,
                style: TextStyle(color: ThemeVars.colorTextSec),
              ),
              const SizedBox(height: 8),
              Text(
                '长按二维码分享或保存',
                style: TextStyle(
                  color: ThemeVars.colorTextSec,
                  fontSize: 12,
                ),
              ),
            ],
          ),
          actions: <Widget>[
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text('关闭'),
            ),
          ],
        );
      },
    );
  }

  /// 分享二维码
  static Future<void> _saveQRCode(BuildContext context, String data) async {
    try {
      // 显示加载提示
      EasyLoading.show(status: '正在生成二维码...');

      // 创建二维码画布
      final painter = QrPainter(
        data: data,
        version: QrVersions.auto,
        errorCorrectionLevel: QrErrorCorrectLevel.L,
        color: Colors.black,
        emptyColor: Colors.white,
      );

      // 创建图片
      final picRecorder = ui.PictureRecorder();
      final canvas = Canvas(picRecorder);
      const size = 512.0; // 使用更高的分辨率
      painter.paint(canvas, const Size(size, size));
      final pic = picRecorder.endRecording();
      final img = await pic.toImage(size.toInt(), size.toInt());
      final byteData = await img.toByteData(format: ui.ImageByteFormat.png);
      final pngBytes = byteData!.buffer.asUint8List();

      // 创建临时文件用于分享
      final tempDir = Directory.systemTemp;
      final file = File('${tempDir.path}/qrcode_${DateTime.now().millisecondsSinceEpoch}.png');
      await file.writeAsBytes(pngBytes);

      // 关闭加载提示
      EasyLoading.dismiss();

      // 分享文件
      await Share.shareXFiles(
        [XFile(file.path)],
        text: '二维码分享',
        subject: '扫描二维码',
      );

      EasyLoading.showSuccess('二维码已生成，可通过分享保存到相册');
      
    } catch (e) {
      // 关闭加载提示
      EasyLoading.dismiss();
      
      print('生成二维码错误: $e');
      EasyLoading.showError('生成失败: $e');
    }
  }
}